package timing.ukulele.bridge.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import lombok.extern.slf4j.Slf4j;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import timing.ukulele.bridge.utils.SecurityUtils;
import timing.ukulele.common.bridge.WeChatMethodEnum;
import timing.ukulele.common.bridge.WeChatRequestData;
import timing.ukulele.common.data.ResponseData;
import timing.ukulele.http.OkHttpManager;

import java.io.IOException;
import java.util.Objects;

@RestController()
@RequestMapping("/weChat")
@Slf4j
public class WeChatController {
    @GetMapping("/test")
    public ResponseData<String> test() {
        return ResponseData.success("恭喜，你成功接入了微信接口");
    }

    @GetMapping("/publicKey/{appId}")
    public ResponseData<String> publicKey(@PathVariable String appId) {
        String contentData = SecurityUtils.getContentData("cert/" + appId + "/publicKey.txt");
        return ResponseData.success(contentData);
    }

    @PostMapping("/gateway/{appId}")
    public ResponseData<String> gateway(@PathVariable("appId") String appId,
                                        @RequestParam("method") String method,
                                        @RequestBody String signedParams) {
        if (!WeChatMethodEnum.hasMethod(method)) {
            return ResponseData.error("暂不支持该方法");
        }
        if (!StringUtils.hasText(signedParams)) {
            return ResponseData.error("参数未传！");
        }
        String privateKey = SecurityUtils.getContentData("cert/" + appId + "/privateKey.txt");
        if (!StringUtils.hasText(privateKey)) {
            return ResponseData.error("该appId尚未分配私钥");
        }
        String paramsString = SecurityUtils.decrypt(signedParams, privateKey);
        if (paramsString == null) {
            return ResponseData.error("参数解密失败");
        }
        WeChatRequestData data = JSON.parseObject(paramsString, new TypeReference<>() {
        });
        if (!StringUtils.hasLength(data.getUrl()) || !StringUtils.hasLength(data.getHttpMethod())) {
            return ResponseData.error("参数错误，url、httpMethod均不能为空");
        }
        Request.Builder builder = new Request.Builder()
                .url(data.getUrl());
        switch (data.getHttpMethod()) {
            case "post" -> {
                MediaType mediaType = MediaType.parse(StringUtils.hasText(data.getMediaType()) ? data.getMediaType() : "application/json;charset=utf-8");
                okhttp3.RequestBody body = okhttp3.RequestBody.create(JSON.toJSONString(data.getParams()), mediaType);
                builder.post(body);
            }
            case "get" -> builder.get();
            case "put" -> {
                MediaType mediaType = MediaType.parse(StringUtils.hasText(data.getMediaType()) ? data.getMediaType() : "application/json;charset=utf-8");
                okhttp3.RequestBody body = okhttp3.RequestBody.create(JSON.toJSONString(data.getParams()), mediaType);
                builder.put(body);
            }
            case "delete" -> builder.delete();
            default -> {
                return ResponseData.error("暂时不支持该请求方法");
            }
        }
        Request request = builder.build();
        try (Response response = OkHttpManager.INSTANCE.build(null).getClient().newCall(request).execute()) {
            if (response.isSuccessful()) {
                try {
                    String responseBody = Objects.requireNonNull(response.body()).string();
                    return ResponseData.success(responseBody);
                } catch (IOException e) {
                    log.error("gateway", e);
                }
            }
            return ResponseData.error(response.message());
        } catch (IOException e) {
            log.error("gateway", e);
        }
        return ResponseData.error("调用失败，未知原因");
    }
}
